package com.learning.gwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class GwtDemo implements EntryPoint {

	private double total = 0;
	private double rightSide = 0;
	private char operator = 0;
	private TextBox display = new TextBox();
	private VerticalPanel mainPanel = new VerticalPanel();

	CalcCheckerAsync calcCheckerService = GWT.create(CalcChecker.class);
	
	public enum ButtonType {
		ONE,
		TWO,
		THREE,
		FOUR,
		FIVE,
		SIX,
		SEVEN,
		EIGHT,
		NINE,
		ZERO,
		PLUS,
		MINUS,
		DIVIDE,
		MULTIPLY,
		EQUALS,
		CLEAR;
	}
	
	public class CustomClickHandler implements ClickHandler {

		private ButtonType buttonType;
		
		public CustomClickHandler(ButtonType buttonType) {
			this.buttonType = buttonType;
		}
		
		@Override
		public void onClick(ClickEvent event) {
			switch (buttonType) {
				case ONE:
					if (operator == 0) {
						total *= 10;
						total += 1;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 1;
						display.setText("" + rightSide);
					}
					break;
				case TWO:
					if (operator == 0) {
						total *= 10;
						total += 2;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 2;
						display.setText("" + rightSide);
					}
					break;
				case THREE:
					if (operator == 0) {
						total *= 10;
						total += 3;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 3;
						display.setText("" + rightSide);
					}
					break;
				case FOUR:
					if (operator == 0) {
						total *= 10;
						total += 4;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 4;
						display.setText("" + rightSide);
					}
					break;
				case FIVE:
					if (operator == 0) {
						total *= 10;
						total += 5;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 5;
						display.setText("" + rightSide);
					}
					break;
				case SIX:
					if (operator == 0) {
						total *= 10;
						total += 6;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 6;
						display.setText("" + rightSide);
					}
					break;
				case SEVEN:
					if (operator == 0) {
						total *= 10;
						total += 7;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 7;
						display.setText("" + rightSide);
					}
					break;
				case EIGHT:
					if (operator == 0) {
						total *= 10;
						total += 8;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 8;
						display.setText("" + rightSide);
					}
					break;
				case NINE:
					if (operator == 0) {
						total *= 10;
						total += 9;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						rightSide += 9;
						display.setText("" + rightSide);
					}
					break;
				case ZERO:
					if (operator == 0) {
						total *= 10;
						display.setText("" + total);
					} else if (operator != 0) {
						rightSide *= 10;
						display.setText("" + rightSide);
					}
					break;
				case PLUS: 
					performOperation('+');
					break;
				case MINUS:
					performOperation('-');
					break;
				case DIVIDE:
					performOperation('/');
					break;
				case MULTIPLY:
					performOperation('*');
					break;
				case EQUALS:
					performOperation('0');
					break;
				case CLEAR:
					rightSide = 0;
					total = 0;
					operator = 0;
					display.setText("lval");
					break;
			}
		}
		
	}
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		final Button clearButton = new Button("Clear");
		display.setText("0");
		final Label errorLabel = new Label();

		// TODO Add the buttons
		Button one = new Button("1");
		Button two = new Button("2");
		Button three = new Button("3");
		Button four = new Button("4");
		Button five = new Button("5");
		Button six = new Button("6");
		Button seven = new Button("7");
		Button eight = new Button("8");
		Button nine = new Button("9");
		Button zero = new Button("0");
		Button subtract = new Button("-");
		Button add = new Button("+");
		Button divide = new Button("/");
		Button multiply = new Button("*");
		Button equals = new Button("=");
		// TODO Assemble the Panel
		mainPanel.add(display);
		mainPanel.add(clearButton);
		mainPanel.add(one);
		mainPanel.add(two);
		mainPanel.add(three);
		mainPanel.add(four);
		mainPanel.add(five);
		mainPanel.add(six);
		mainPanel.add(seven);
		mainPanel.add(eight);
		mainPanel.add(nine);
		mainPanel.add(zero);
		mainPanel.add(subtract);
		mainPanel.add(add);
		mainPanel.add(multiply);
		mainPanel.add(divide);
		mainPanel.add(equals);

		RootPanel.get();
		RootPanel.get("mainPanel").add(mainPanel);

		// Focus the cursor on the Display when the app loads
		display.setFocus(true);
		display.selectAll();
		

		// Create handlers for the number buttons
		one.addClickHandler(new CustomClickHandler(ButtonType.ONE));
		two.addClickHandler(new CustomClickHandler(ButtonType.TWO));
		three.addClickHandler(new CustomClickHandler(ButtonType.THREE));
		four.addClickHandler(new CustomClickHandler(ButtonType.FOUR));
		five.addClickHandler(new CustomClickHandler(ButtonType.FIVE));
		six.addClickHandler(new CustomClickHandler(ButtonType.SIX));
		seven.addClickHandler(new CustomClickHandler(ButtonType.SEVEN));
		eight.addClickHandler(new CustomClickHandler(ButtonType.EIGHT));
		nine.addClickHandler(new CustomClickHandler(ButtonType.NINE));
		zero.addClickHandler(new CustomClickHandler(ButtonType.ZERO));
		// implement handlers for the operator buttons.
		add.addClickHandler(new CustomClickHandler(ButtonType.PLUS));
		subtract.addClickHandler(new CustomClickHandler(ButtonType.MINUS));
		multiply.addClickHandler(new CustomClickHandler(ButtonType.MULTIPLY));
		divide.addClickHandler(new CustomClickHandler(ButtonType.DIVIDE));
		equals.addClickHandler(new CustomClickHandler(ButtonType.EQUALS));
		clearButton.addClickHandler(new CustomClickHandler(ButtonType.CLEAR));

	}
	
	public void performOperation(final char c) {
		double[] values = {total, rightSide};
		
		calcCheckerService.checkInput(values, new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					switch (operator) {
						case '+': 
							total += rightSide;
							rightSide = 0;
							operator = 0;
							display.setText(""+total);
							break;
						case '-':
							total -= rightSide;
							rightSide = 0;
							operator = 0;
							display.setText(""+total);
							break;
						case '/':
							total /= rightSide;
							rightSide = 0;
							operator = 0;
							display.setText(""+total);
							break;
						case '*':
							total *= rightSide;
							rightSide = 0;
							operator = 0;
							display.setText(""+total);
							break;
						case '0':
							break;
						}
						
						operator = c;
				} else {
					// dostuff
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});
	}
}
